require "kuru_wrap.lua"
require "xmath.lua"
require "ShaderSticker_180904.lua"

M_PI = 3.14159265358979

SnapState = {
  NORMAL = 0,
  OKING = 1,
  OKED = 2,
  SCISSORING = 3,
  SCISSORED= 4,
  FINGERINDEXING = 5,
  FINGERINDEXED = 6,
  SNAPSHOT = 7,
}

--focusConfig ={path='306748_2_plain/b_bb',type=1,scale=2.4,tx=0,ty=0,anchor=KaleStickerNodeAnchorType.CENTER,location=KaleStickerNodeLocationType.FACE,flip=false,fps=20,blendmode=BlendMode.Normal}
signalConfig ={path='306748_2_plain/b_ss',type=0,scale=1,tx=0,ty=0,anchor=KuruBackgroundImageNodeAnchorType.CENTER,stretch=KuruBackgroundImageNodeStretch.UNIFORM_FILL,fps=20,blendmode=BlendMode.None}
bxzConfig1={path='306748_2_plain/b_xz1',type=0,scale=1,tx=0,ty=0,anchor=KuruBackgroundImageNodeAnchorType.CENTER,stretch=KuruBackgroundImageNodeStretch.UNIFORM_FILL,fps=20,blendmode=BlendMode.None}
bxzConfig2={path='306748_2_plain/b_xz2',type=0,scale=1,tx=0,ty=0,anchor=KuruBackgroundImageNodeAnchorType.CENTER,stretch=KuruBackgroundImageNodeStretch.UNIFORM_FILL,fps=20,blendmode=BlendMode.None}
bxzConfig3={path='306748_2_plain/b_xz3',type=0,scale=1,tx=0,ty=0,anchor=KuruBackgroundImageNodeAnchorType.CENTER,stretch=KuruBackgroundImageNodeStretch.UNIFORM_FILL,fps=20,blendmode=BlendMode.None}
foucsNode = nil
signalNode = nil
-- bxzNode1 = nil
-- bxzNode2 = nil
-- bxzNode3 = nil
g_framebuffer1 = nil
g_framebuffer2 = nil
g_framebuffer3 = nil
state = SnapState.NORMAL
isVideoing = false
g_kacaProgress = 0
g_scaleProgress = 0
g_bufferTimer = 0
g_autoShotTimer = 0
isSoundPalying = false
function initialize(scene)
 
  kuruEngineInstance = KuruEngine.getInstance()
  scene:getInternalScene():setHandDetection(true)
  kuruBody = KuruHumanActionExtension.cast(kuruEngineInstance:getExtension("KuruHumanAction"))

  -- soundExtension = KuruSoundExtension.cast(KuruEngine.getInstance():getExtension("KuruSound"))
  -- sound1 = soundExtension:loadEx(BASE_DIRECTORY..("kacha.mp3"))

  snapShot1 = getCurrentSnapshot(scene,1.0)
  snapShot2 = getCurrentSnapshot(scene,1.0)
  snapShot3 = getCurrentSnapshot(scene,1.0)

 -- foucsNode = KuruWrap.addNodeWithConfig(scene,focusConfig)
  signalNode = KuruWrap.addNodeWithConfig(scene,signalConfig)

  local width = 2.5
  local height = width*9.0/16.0*630.0/582.0
  --focussampler = getStickerSampler("306748_2_plain/b_bb",20)
  focussampler = KuruAnimationSampler.createFromPath(BASE_DIRECTORY.."306748_2_plain/b_bb",false,false)
  focusnode = KuruFloatingImageNode.createFromSampler(focussampler,-1-(width/2-1),-1+(1-height/2),width,height,BlendMode.None)
  addNodeAndRelease(scene,focusnode)
  focussampler:release()
  focusnode:setEnabled(false)
  -- kacaeffect = KaCaEffect:new(scene,KaCaEffectType.effectType_fromLeft)
  
  g_framebuffer1=  addNodeAndRelease(scene, KuruFrameBufferNode.create())
  local g_bgNode1 = addChildAndRelease(g_framebuffer1, KuruBackgroundImageNode.createFromSampler(snapShot1:getSampler(), BlendMode.None))
  local bxzNode1 = KuruWrap.getNodeWithConfig(bxzConfig1,nil)
  addChildAndRelease(g_framebuffer1,bxzNode1)
  local crop1 = KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY .. "crop1.frag", true)
  addChildAndRelease(g_framebuffer1,crop1)
  g_kacaNode1 = KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY.."kaca3.frag",true)
  addChildAndRelease(g_framebuffer1,g_kacaNode1)
  --g_kacaNode1:getMaterial():getParameter("whiteIntensity"):setFloat(0.1)
  -- g_kacaNode1:setEnabled(false) --咔擦动画，每点击一次就屏幕就闪一下 
  -- local g_snap1 =  KuruSnapshotNode.create()
  -- addChildAndRelease(g)
  local offsetY = 0.3
  local bottomY = 0.3
  -- floatImage1 = KuruFloatingImageNode.createFromSampler(g_framebuffer1:getSampler(),-1,-1+bottomY,2,2-bottomY-offsetY,BlendMode.None)
  -- floatImage1:setEnabled(false)
  -- addNodeAndRelease(scene,floatImage1)
  sec1 = addSection(scene, g_framebuffer1:getSampler()) 
  local matInfo1 = Matrix.createFromMatrix(Matrix.identity())
  matInfo1:postScale(1.0,0.7,1.0)
  sec1.material:getParameter("u_worldViewProjectionMatrix"):setMatrix(matInfo1)

  local fMat = Matrix.createFromMatrix(Matrix.identity())
  
  sec1.material:getParameter("u_matrix"):setMatrix(fMat)
  sec1.node:setEnabled(false)

  g_framebuffer3=  addNodeAndRelease(scene, KuruFrameBufferNode.create())
  local g_bgNode3 = addChildAndRelease(g_framebuffer3, KuruBackgroundImageNode.createFromSampler(snapShot3:getSampler(), BlendMode.None))
  local bxzNode3 = KuruWrap.getNodeWithConfig(bxzConfig3,nil)
  addChildAndRelease(g_framebuffer3,bxzNode3)
  local crop3 = KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY .. "crop1.frag", true)
  addChildAndRelease(g_framebuffer3,crop3)
  g_kacaNode3 = KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY.."kaca3.frag",true)
  addChildAndRelease(g_framebuffer3,g_kacaNode3)
  sec3 = addSection(scene, g_framebuffer3:getSampler()) 
  local matInfo3 = Matrix.createFromMatrix(Matrix.identity())
  matInfo3:postScale(1.0,0.7,1.0)
  sec3.material:getParameter("u_worldViewProjectionMatrix"):setMatrix(matInfo3)
  sec3.material:getParameter("u_matrix"):setMatrix(fMat)
  sec3.node:setEnabled(false)

  g_framebuffer2=  addNodeAndRelease(scene, KuruFrameBufferNode.create())
  local g_bgNode2 = addChildAndRelease(g_framebuffer2, KuruBackgroundImageNode.createFromSampler(snapShot2:getSampler(), BlendMode.None))
  local bxzNode2 = KuruWrap.getNodeWithConfig(bxzConfig2,nil)
  addChildAndRelease(g_framebuffer2,bxzNode2)
  local crop2 = KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY .. "crop1.frag", true)
  addChildAndRelease(g_framebuffer2,crop2)
  g_kacaNode2 = KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY.."kaca3.frag",true)
  addChildAndRelease(g_framebuffer2,g_kacaNode2)
  sec2 = addSection(scene, g_framebuffer2:getSampler()) 
  local matInfo2 = Matrix.createFromMatrix(Matrix.identity())
  matInfo2:postScale(1.0,0.7,1.0)
  sec2.material:getParameter("u_worldViewProjectionMatrix"):setMatrix(matInfo2)


  sec2.material:getParameter("u_matrix"):setMatrix(fMat)
  sec2.node:setEnabled(false)



end

function getCurrentSnapshot(scene, bufferScale)
  local node = KuruSnapshotNode.create()
  scene:addNode(node)
  node:release()
  node:setFrameBufferScale(bufferScale, bufferScale)
  return node
end

function getStickerSampler(filepath,fps)
  local sp = KuruAnimationSampler.createFromPath(BASE_DIRECTORY..filepath,false,false)
  sp:setRepeatCount(0)
  sp:setFPS(fps)
  sp:play()

  return sp
end

function reset(scene)

  --sound1:stop()
end

function frameReady(scene, elapsedTime)
 
if SceneRenderConfig.instance():isRenderModePreview() then
  if state == SnapState.SNAPSHOT or isVideoing then
      state = SnapState.NORMAL
      resetState()
      isVideoing = false
  end
  if state == SnapState.FINGERINDEXED and g_autoShotTimer>5.0 then
    state = SnapState.NORMAL
    resetState()
  elseif state == SnapState.FINGERINDEXED then
        g_autoShotTimer =  g_autoShotTimer+elapsedTime / 1000.0
  end
elseif  SceneRenderConfig.instance():isRenderModeSnapshot() then
    state = SnapState.SNAPSHOT
elseif SceneRenderConfig.instance():isRenderModeVideo() then
   -- g_state = SnapState.SNAPSHOT
   if isVideoing==false then
      isVideoing = true
      resetState()
      state = SnapState.NORMAL
   end
    print("isRenderModeVideo")
else

end

  if state==SnapState.OKING then
  
      if g_kacaProgress>1 then
        focusnode:setEnabled(false)
        isSoundPalying = false
        if g_scaleProgress>0.5 then
            g_kacaProgress = 0.0
            g_scaleProgress = 0.0
            g_bufferTimer = 0
            state=SnapState.OKED
        else
          g_scaleProgress = g_scaleProgress + 0.1
            local matInfo1 = Matrix.createFromMatrix(Matrix.identity())
            matInfo1:postScale(1.0,0.7,1.0)
            matInfo1:postScale(1.0,16/9.0,1.0)
            matInfo1:postRotateZ(M_PI/18*g_scaleProgress)
           matInfo1:postScale(1.0,9/16.0,1.0)
          --  matInfo1:postScale(0.5,0.5,1.0)
           matInfo1:postScale(1-g_scaleProgress*1,1-g_scaleProgress*1,1.0)
           
           matInfo1:postTranslate(-g_scaleProgress, g_scaleProgress*1.2, 0.0)
            sec1.material:getParameter("u_worldViewProjectionMatrix"):setMatrix(matInfo1)

            local fMat = Matrix.createFromMatrix(Matrix.identity())
            sec1.material:getParameter("u_matrix"):setMatrix(fMat)
        end
    
      else
        g_kacaProgress = g_kacaProgress + elapsedTime / 1000.0 * 2
        -- if isSoundPalying==false then
        --   sound1:play(false)
        --   isSoundPalying = true
        -- end
        
        g_kacaNode1:getMaterial():getParameter("whiteIntensity"):setFloat(pingpongLerp(0,1,g_kacaProgress))
      end
    
  end
  if state==SnapState.SCISSORING then
  if g_kacaProgress>1 then
    isSoundPalying = false
    focusnode:setEnabled(false)
    if g_scaleProgress>0.5 then
        g_kacaProgress = 0.0
        g_scaleProgress = 0.0
        state=SnapState.SCISSORED
    else
      g_scaleProgress = g_scaleProgress + 0.1
        local matInfo1 = Matrix.createFromMatrix(Matrix.identity())
        matInfo1:postScale(1.0,0.7,1.0)
       matInfo1:postScale(1-g_scaleProgress*1,1-g_scaleProgress*1,1.0)
       
       matInfo1:postTranslate(0, g_scaleProgress*1.1, 0.0)
        sec2.material:getParameter("u_worldViewProjectionMatrix"):setMatrix(matInfo1)

        local fMat = Matrix.createFromMatrix(Matrix.identity())
        sec2.material:getParameter("u_matrix"):setMatrix(fMat)
    end

  else
      -- if isSoundPalying==false then
      --   sound1:play(false)
      --   isSoundPalying = true
      -- end
      g_kacaProgress = g_kacaProgress + elapsedTime / 1000.0 * 2
      g_kacaNode2:getMaterial():getParameter("whiteIntensity"):setFloat(pingpongLerp(0,1,g_kacaProgress))
  end
  end
  if state==SnapState.FINGERINDEXING then
      if g_kacaProgress>1 then
        isSoundPalying = false
        focusnode:setEnabled(false)
        if g_scaleProgress>0.5 then
            g_kacaProgress = 0.0
            g_scaleProgress = 0.0
            state=SnapState.FINGERINDEXED
        else
          g_scaleProgress = g_scaleProgress + 0.1
            local matInfo1 = Matrix.createFromMatrix(Matrix.identity())
            matInfo1:postScale(1.0,0.7,1.0)
            matInfo1:postScale(1.0,16/9.0,1.0)
            matInfo1:postRotateZ(-M_PI/18*g_scaleProgress)
           matInfo1:postScale(1.0,9/16.0,1.0)
          --  matInfo1:postScale(0.5,0.5,1.0)
           matInfo1:postScale(1-g_scaleProgress*1,1-g_scaleProgress*1,1.0)
           
           matInfo1:postTranslate(g_scaleProgress, g_scaleProgress*1.15, 0.0)
            sec3.material:getParameter("u_worldViewProjectionMatrix"):setMatrix(matInfo1)

            local fMat = Matrix.createFromMatrix(Matrix.identity())
            sec3.material:getParameter("u_matrix"):setMatrix(fMat)
        end
    
      else
        -- if isSoundPalying==false then
        --   sound1:play(false)
        --   isSoundPalying = true
        -- end
        g_kacaProgress = g_kacaProgress + elapsedTime / 1000.0 * 2
        g_kacaNode3:getMaterial():getParameter("whiteIntensity"):setFloat(pingpongLerp(0,1,g_kacaProgress))
      end
  end
  local handCount = kuruBody:getHandCount()
  if handCount > 0 then
    for i = 0, handCount - 1 do
      local hand = kuruBody:getHandData(i)
      local vec2 = hand:getKeyPoint(0)
      local handRect = hand:getHandRect()
      if vec2.x > -10000 then
        if hand:isOK() then 
            print("isOK")
            if state == SnapState.NORMAL then
              if g_bufferTimer<1.0 then
                g_bufferTimer = g_bufferTimer+elapsedTime / 1000.0
                if focusnode:isEnabled()==false then
                  focussampler:stop()
                  focussampler:setRepeatCount(0)
                  focussampler:setFPS(30)
                  focussampler:play()
                  focusnode:setEnabled(true)
                end
              else
                snapShot1:setEnabled(false)
                sec1.node:setEnabled(true)
                g_kacaNode1:setEnabled(true) 
                state = SnapState.OKING
                g_bufferTimer =0
              end
              
            end
        end
        if hand:isScissor() then
          if state == SnapState.OKED then
            if g_bufferTimer<1.0 then
            g_bufferTimer = g_bufferTimer+elapsedTime / 1000.0
            if focusnode:isEnabled()==false then
              focussampler:stop()
              focussampler:setRepeatCount(0)
              focussampler:setFPS(30)
              focussampler:play()
              focusnode:setEnabled(true)
            end
            else
            snapShot2:setEnabled(false)
            -- floatImage1:setEnabled(true)
            sec2.node:setEnabled(true)
            g_kacaNode2:setEnabled(true) 
            state = SnapState.SCISSORING
            g_bufferTimer =0
            end
          end
        end
        if hand:isFingerIndex() then 
          if state == SnapState.SCISSORED then
            if g_bufferTimer<1.0 then
            g_bufferTimer = g_bufferTimer+elapsedTime / 1000.0
            if focusnode:isEnabled()==false then
              focussampler:stop()
              focussampler:setRepeatCount(0)
              focussampler:setFPS(30)
              focussampler:play()
              focusnode:setEnabled(true)
            end
            else
            snapShot3:setEnabled(false)
            -- floatImage1:setEnabled(true)
            sec3.node:setEnabled(true)
            g_kacaNode3:setEnabled(true) 
            state = SnapState.FINGERINDEXING
            g_bufferTimer =0
            end
      end
        end
       
      end
    end
  else
    focusnode:setEnabled(false)
    g_bufferTimer=0.0
  end
end

function finalize(scene)
 
  
end


function resetState()

  g_autoShotTimer=0.0

  local matInfo1 = Matrix.createFromMatrix(Matrix.identity())
  matInfo1:postScale(1.0,0.7,1.0)
  sec1.material:getParameter("u_worldViewProjectionMatrix"):setMatrix(matInfo1)

  local fMat = Matrix.createFromMatrix(Matrix.identity())
  
  sec1.material:getParameter("u_matrix"):setMatrix(fMat)
  sec1.node:setEnabled(false)

  local matInfo2 = Matrix.createFromMatrix(Matrix.identity())
  matInfo2:postScale(1.0,0.7,1.0)
  sec2.material:getParameter("u_worldViewProjectionMatrix"):setMatrix(matInfo2)
  sec2.material:getParameter("u_matrix"):setMatrix(fMat)

  local matInfo3 = Matrix.createFromMatrix(Matrix.identity())
  matInfo3:postScale(1.0,0.7,1.0)
  sec3.material:getParameter("u_worldViewProjectionMatrix"):setMatrix(matInfo3)
  sec3.material:getParameter("u_matrix"):setMatrix(fMat)

  snapShot1:setEnabled(true)
  sec1.node:setEnabled(false)

  snapShot2:setEnabled(true)
  sec2.node:setEnabled(false)

  snapShot3:setEnabled(true)
  sec3.node:setEnabled(false)

end

function addSection(scene, sampler)
  local sWidth = KuruEngine.getInstance():getResolution().x / 2.0
  local sHeight = KuruEngine.getInstance():getResolution().y / 2.0

  local aspectRatio = sWidth / sHeight
  local fragShader = BASE_DIRECTORY .. "transform2.frag"

  local sectionNode = ShaderSticker:new(sampler, sWidth, sHeight, {blendSrc=RenderStateBlend.BLEND_ONE, fragShader=fragShader})
  addNodeAndRelease(scene, sectionNode.node)  

  return sectionNode
end

function addNodeAndRelease(scene, node)
    scene:addNode(node)
    node:release()
    return node
end

function addChildAndRelease(node,subNode)
  node:addChild(subNode)
  subNode:release()
  return node
end



function createSegNode(scene, distortionNode, snapshotNode)
  local seg = KuruSegmentationNode.create()
  seg:setSourceSampler(snapshotNode:getSnapshot())
 -- seg:setDistortionNode(distortionNode)
  scene:addNode(seg)
  seg:release()
  return seg
end

function getSnapshot2(scene, bufferScale)
    local node = KuruSnapshotNode.create()
    scene:addNode(node)
    node:release()
    node:setFrameBufferScale(bufferScale, bufferScale)
    return node
end

